package com.ozo.boot.manage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ozo.boot.common.base.model.BaseBatchDTO;
import com.ozo.boot.common.core.exception.ServiceException;
import com.ozo.boot.common.database.util.SortUtils;
import com.ozo.boot.manage.exception.ManageExceptionEnum;
import com.ozo.boot.manage.pojo.dto.ChangeStatusDTO;
import com.ozo.boot.manage.pojo.dto.SysDeptQueryDTO;
import com.ozo.boot.manage.pojo.dto.SysDeptSaveDTO;
import com.ozo.boot.manage.entity.SysDept;
import com.ozo.boot.manage.entity.SysUser;
import com.ozo.boot.manage.mapper.SysDeptMapper;
import com.ozo.boot.manage.mapper.SysUserMapper;
import com.ozo.boot.manage.pojo.vo.SysDeptVO;
import com.ozo.boot.manage.service.ISysDeptService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @since 2024-07-11
 */
@RequiredArgsConstructor
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    private final SysUserMapper sysUserMapper;

    @Override
    public void add(SysDeptSaveDTO saveDTO) {
        // 参数校验
        this.checkParam(null, saveDTO.getParentId(), saveDTO.getDeptName());

        SysDept sysDept = BeanUtil.copyProperties(saveDTO, SysDept.class);
        baseMapper.insert(sysDept);
    }

    /**
     * 合法性校验
     *
     * @param id
     * @param parentId
     * @param deptName
     */
    private void checkParam(Long id, Long parentId, String deptName) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDept::getParentId, parentId)
                .eq(SysDept::getDeptName, deptName)
                .ne(Objects.nonNull(id), SysDept::getId, id);
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ServiceException(ManageExceptionEnum.DEPT_NAME_EXISTS);
        }
    }

    @Override
    public void remove(BaseBatchDTO<Long> batchDTO) {
        List<Long> idList = batchDTO.getIdList();

        // 删除前校验
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysUser::getDeptId, idList);
        long userCount = sysUserMapper.selectCount(queryWrapper);
        if (userCount > 0) {
            throw new ServiceException(ManageExceptionEnum.DEPT_HAS_USER_NOT_DELETE);
        }

        baseMapper.deleteBatchIds(idList);
    }

    @Override
    public void edit(SysDeptSaveDTO saveDTO) {
        // 参数校验
        this.checkParam(saveDTO.getId(), saveDTO.getParentId(), saveDTO.getDeptName());

        SysDept sysDept = BeanUtil.copyProperties(saveDTO, SysDept.class);
        baseMapper.updateById(sysDept);
    }

    @Override
    public List<SysDeptVO> list(SysDeptQueryDTO queryDTO) {
        QueryWrapper<SysDept> queryWrapper = new QueryWrapper<>();
        // 排序
        String order = queryDTO.getOrder();
        if (StrUtil.isBlank(order)) {
            queryWrapper.lambda().orderByAsc(SysDept::getOrderNum);
        } else {
            SortUtils.setSortCondition(queryWrapper, queryDTO.getProp(), order);
        }
        // 条件
        queryWrapper.lambda()
                .like(StrUtil.isNotBlank(queryDTO.getDeptName()), SysDept::getDeptName, queryDTO.getDeptName())
                .eq(StrUtil.isNotBlank(queryDTO.getStatus()), SysDept::getStatus, queryDTO.getStatus());
        List<SysDept> sysDeptList = baseMapper.selectList(queryWrapper);

        List<SysDeptVO> sysDeptVOList = BeanUtil.copyToList(sysDeptList, SysDeptVO.class);

        for (SysDeptVO sysDeptVO : sysDeptVOList) {
            List<SysDeptVO> children = sysDeptVOList.stream().filter(e -> sysDeptVO.getId().equals(e.getParentId())).collect(Collectors.toList());
            sysDeptVO.setChildren(children);
        }
        return sysDeptVOList.stream().filter(e -> e.getParentId() == null).collect(Collectors.toList());
    }

    @Override
    public void changeStatus(ChangeStatusDTO statusDTO) {
        LambdaUpdateWrapper<SysDept> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SysDept::getId, statusDTO.getId())
                .set(SysDept::getStatus, statusDTO.getStatus());
        baseMapper.update(updateWrapper);
    }

    @Override
    public SysDeptVO getByUserId(Long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (Objects.nonNull(sysUser)) {
            SysDept sysDept = baseMapper.selectById(sysUser.getDeptId());
            return BeanUtil.copyProperties(sysDept, SysDeptVO.class);
        }
        return null;
    }

}
